package com.cherry.ssm.user.service.impl;


import java.util.Date;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import com.cherry.ssm.user.dao.UserMapper;
import com.cherry.ssm.user.model.SsoUser;
import com.cherry.ssm.user.service.UserService;
import com.cherry.ssm.util.Constant;
import com.cherry.ssm.util.Guid;
import com.cherry.ssm.util.RandomMD5;
import com.cherry.ssm.util.model.SsoLoginCache;
import com.cherry.ssm.util.service.SsoDictValService;
import com.cherry.ssm.util.service.SsoLoginCacheService;


@Service
public class UserServiceImpl implements UserService {

	@Autowired
    private UserMapper userMapper;
	
	@Autowired
    private SsoDictValService ssoDictValService;
	@Autowired
	private SsoLoginCacheService ssoLoginCacheService;
	
	private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
	
	
	/**
	 * 登陆接口
	 * 1、拿到客户端之前验证接入权限的时候获取的客户端本地的ip
	 * 2、判断是否登陆成功
	 * 3、得到code、token、loginId
	 * 4、根据登陆账号loginId来判断是否缓存,如果缓存则修改,如果没缓存则添加
	 * 5、生成code的Cookie
	 * 6、重定向到客户端接口或者登陆失败页
	 */
	public String login(SsoUser users,HttpServletRequest request, HttpServletResponse response, HttpSession session) throws OAuthSystemException{
		System.out.println("/login");
		
		String loginId = users.getLoginId();
		String passWord = users.getPassWord();
		if(loginId != null && loginId.length() != 0 && passWord != null && passWord.length() != 0){
			
			//客户端之前验证接入权限的时候获取的客户端本地的ip
			String str = session.getAttribute(Constant.REQUEST_IP).toString();
			String ip = null;
			try {
				ip = RandomMD5.aesDecrypt(str,Constant.AES_KEY_SSO);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if(ip != null && ip.length() > 0){
				Integer sum = this.userMapper.getCount(loginId,passWord);
				if(sum > 0){
					/**
					 * 生成code存入cookie,重定向到客户端
					 */
					String token = loginId;
					String code = Guid.guid();
					// 根据登陆账号loginId来判断是否缓存,如果缓存则修改,如果没缓存则添加
					SsoLoginCache ssoLoginCache= new SsoLoginCache();
					ssoLoginCache.setSsoLoginCode(code);
					ssoLoginCache.setSsoLoginToken(token);
					Boolean bool = true;
					if(this.ssoLoginCacheService.getEntityByLoginToken(token) == null){
						this.ssoLoginCacheService.insertSsoLoginCache(ssoLoginCache);
					}else{
						bool = this.ssoLoginCacheService.updateSsoLoginCache(ssoLoginCache);
					}
					if(bool){
						// 通过重新定向到客户端接口,所以为了安全只会暴露code
						Cookie cookieCode = new Cookie("code", code);   // 新建一个Cookie对象
						cookieCode.setMaxAge(-1);   // 设置过期时间,以秒为单位;如果设置为负值的话,则为浏览器进程Cookie(内存中保存),关闭浏览器就失效;不设置的话,则cookies不写入硬盘,而是写在内存,只在当前页面有用
						cookieCode.setPath("/");   // 同一应用服务器内共享方法
						response.addCookie(cookieCode);
						
						return "redirect:"+session.getAttribute(Constant.CLIENT_INTERCEPT_KEY)+"?code="+code+"&client_url="+session.getAttribute(Constant.CLIENT_URL_KEY);
					}else{
						// 通过重新定向到客户端接口,所以为了安全只会暴露code
						Cookie cookieCode = new Cookie("code", null);   // 新建一个Cookie对象
						cookieCode.setMaxAge(-1);   // 设置过期时间,以秒为单位;如果设置为负值的话,则为浏览器进程Cookie(内存中保存),关闭浏览器就失效;不设置的话,则cookies不写入硬盘,而是写在内存,只在当前页面有用
						cookieCode.setPath("/");   // 同一应用服务器内共享方法
						response.addCookie(cookieCode);
						
						log.error("登陆失败  "+new Date());
						return "login/login_error";
					}
				}else{
					log.error("登陆失败  "+new Date());
					return "login/login_error";
				}
			}else{
				log.error("非法请求","session.getAttribute(Constant.REQUEST_IP).toString()为空或长度为零");
				return "login/unlawful";
			}
		}
		log.error("登陆失败  "+new Date());
		return "login/login_error";
	}
	
	
	/**
	 * 通过code获取token
	 * 通过token获取loginId
	 */
	public HttpEntity getloginId(HttpServletRequest request, HttpSession session){
		System.out.println("/getloginId");
		
		/**
		 * 获取从客户端"/client"接口中发送的code
		 * 如果code为空,说明当前客户端非法请求
		 */
		String code = null;
		try {
			OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(request, ParameterStyle.QUERY);
			code = oauthRequest.getAccessToken();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//  得到了重定向的url,判断这个url的ip需要和本次请求的ip是否一样
		String T[] = code.split("&&&");
		code = T[0];
		String client_url=T[1];
		String ip = request.getHeader("X-Forwarded-For");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
		
		System.out.println("client_url:   "+client_url);
		System.out.println("ip:   "+ip);
		
		if(client_url.indexOf(ip) != -1){
			if(code != null && code.length() > 0){
				String sso_code = null;
				String sso_token = null;
				
				SsoLoginCache ssoLoginCache= this.ssoLoginCacheService.getEntityByLoginCode(code);
				if(ssoLoginCache != null){
					sso_code = ssoLoginCache.getSsoLoginCode();
					sso_token = ssoLoginCache.getSsoLoginToken();
				}else{
					log.error("当前客户端非法请求");
					return new ResponseEntity("unlawful", HttpStatus.OK);
				}
				String pro = null;
				try {
					pro = RandomMD5.aesEncrypt(sso_token, Constant.AES_KEY_PRO);
				} catch (Exception e) {
					e.printStackTrace();
				}
				log.error("当前客户端请求成功");
				return new ResponseEntity(pro, HttpStatus.OK);
					
			}else{
				log.error("当前客户端非法请求");
				return new ResponseEntity("unlawful", HttpStatus.OK);
			}
		}else{
			log.error("当前客户端非法请求");
			return new ResponseEntity("unlawful", HttpStatus.OK);
		}
		
	}
	
	
	/**
	 * 退出登陆
	 */
	public String loginout(HttpServletRequest request, HttpServletResponse response, HttpSession session){
		System.out.println("/loginout");
		
		Cookie cookieToken = new Cookie("token", null);
		cookieToken.setMaxAge(3600*24);
		cookieToken.setPath("/");
		response.addCookie(cookieToken);
		
		Cookie cookieCode = new Cookie("code", null);
		cookieCode.setMaxAge(-1);
		cookieCode.setPath("/");
		response.addCookie(cookieCode);
		
		session.setAttribute(Constant.CLIENT_URL_KEY,null);
		session.setAttribute(Constant.CLIENT_INTERCEPT_KEY,null);
		
		return "login/loginout";
		
	}
	
	
	
}
